package com.yxw.yx_hotel.controller;


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.yxw.yxnet_cd_center.common.utils.BaseResult;
import com.yxw.yxnet_cd_center.common.utils.SHASignUtil;
import com.yxw.yxnet_cd_center.common.utils.RSAUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.time.LocalDateTime;
import com.yxw.yx_hotel.vo.LoginUserVo;
import com.yxw.yx_hotel.vo.UserInfoVo;
import com.yxw.yx_hotel.vo.UserTokenVo;
import com.yxw.yx_hotel.entity.YxSysUserEntity;
import com.yxw.yx_hotel.entity.YxHotelRegionEntity;
import com.yxw.yx_hotel.utils.JwtUtil;
import com.yxw.yxnet_cd_center.common.constant.CommonConstant;
import java.util.Map;
import org.springframework.web.bind.annotation.PathVariable;
import com.yxw.yx_hotel.mapper.UserMapper;
import java.util.Date;
import java.util.HashMap;
import org.apache.commons.codec.binary.Base64;
import com.yxw.yx_hotel.utils.MyBase64;
import com.yxw.yx_hotel.utils.JsonUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yxw.yx_hotel.utils.UserUtil;
import javax.servlet.http.HttpServletRequest;
/**
 * @author fangmaoxin
 * @version 1.0
 * @date 2024年1月24日  
 * 登录账号管理相关
 */
@RestController
@Api(value = "测试相关的操作", tags = {"测试相关的操作"})
@Slf4j
@RequestMapping("/hoteltest/v1")
public class TestController {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserUtil userUtil;

    @GetMapping("/headerTest")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @ApiOperation("assignIdTest")
    public BaseResult headerTest() {
        return BaseResult.success(userUtil.getLoginUserVo());
    }    

    @GetMapping("/assignIdTest")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @ApiOperation("assignIdTest")
    public BaseResult assignIdTest() {        
        return BaseResult.doSuccess(null, "IdWorker.getId():" + IdWorker.getId() + "  IdWorker.getIdStr():" + IdWorker.getIdStr() + "  IdWorker.get32UUID():" + IdWorker.get32UUID() + "  IdWorker.getMillisecond():" + IdWorker.getMillisecond() + "  IdWorker.getTimeId():" + IdWorker.getTimeId());
    }
    

    @PostMapping("/sha512test")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @ApiOperation("sha512Test")
    public BaseResult sha512Test(@RequestParam @NotBlank(message = "testString不能为空") String testString) {
        testString = SHASignUtil.SHA512(testString);
        return BaseResult.doSuccess(null, "sha512:" + testString);
    }


    @GetMapping("/rsaTestCreateKeys")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @ApiOperation("rsaTestCreateKeys")
    public BaseResult rsaTestCreateKeys(@RequestParam @NotNull(message = "keySize不能为空") Integer keySize) {
        RSAUtil.createKeys(keySize);
        JSONObject oJSONObject = new JSONObject();
        oJSONObject.put("publicKeyStr", RSAUtil.getPublicKeyStr());
        oJSONObject.put("privateKeyStr", RSAUtil.getPrivateKeyStr());
        return BaseResult.success(oJSONObject);
    }  

    @GetMapping("/rsaTestPublicEncrypt")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @ApiOperation("rsaTestPublicEncrypt")
    public BaseResult rsaTestPublicEncrypt(@RequestParam @NotBlank(message = "publicKey不能为空") String publicKey,@RequestParam @NotBlank(message = "需要加密的数据data不能为空") String data) {
        RSAPublicKey oRSAPublicKey = null;
        try
        {
            oRSAPublicKey = RSAUtil.getPublicKey(publicKey);
        }
        catch(Exception oException)
        {
            return BaseResult.failed(oException.getMessage());
        }
        String dataEncrypt = RSAUtil.publicEncrypt(data, oRSAPublicKey);
        return BaseResult.success(dataEncrypt);
    }

    @GetMapping("/rsaTestPrivateDecrypt")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @ApiOperation("rsaTestPrivateDecrypt")
    public BaseResult rsaTestPrivateDecrypt(@RequestParam @NotBlank(message = "privateKey不能为空") String privateKey,@RequestParam @NotBlank(message = "需要解密的数据dataEncrypt不能为空") String dataEncrypt) {
        RSAPrivateKey oRSAPrivateKey = null;
        try
        {
            oRSAPrivateKey = RSAUtil.getPrivateKey(privateKey);
        }
        catch(Exception oException)
        {
            return BaseResult.failed(oException.getMessage());
        }
        String dataDecrypt = RSAUtil.privateDecrypt(dataEncrypt, oRSAPrivateKey);
        return BaseResult.success(dataDecrypt);
    }

    @GetMapping("/rsaTestPrivateEncrypt")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @ApiOperation("rsaTestPrivateEncrypt")
    public BaseResult rsaTestPrivateEncrypt(@RequestParam @NotBlank(message = "privateKey不能为空") String privateKey,@RequestParam @NotBlank(message = "需要加密的数据data不能为空") String data) {
        RSAPrivateKey oRSAPrivateKey = null;
        try
        {
            oRSAPrivateKey = RSAUtil.getPrivateKey(privateKey);
        }
        catch(Exception oException)
        {
            return BaseResult.failed(oException.getMessage());
        }
        String dataEncrypt = RSAUtil.privateEncrypt(data, oRSAPrivateKey);
        return BaseResult.success(dataEncrypt);
    } 

    @GetMapping("/rsaTestPublicDecrypt")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @ApiOperation("rsaTestPublicDecrypt")
    public BaseResult rsaTestPublicDecrypt(@RequestParam @NotBlank(message = "publicKey不能为空") String publicKey,@RequestParam @NotBlank(message = "需要加密的数据dataEncrypt不能为空") String dataEncrypt) {
        RSAPublicKey oRSAPublicKey = null;
        try
        {
            oRSAPublicKey = RSAUtil.getPublicKey(publicKey);
        }
        catch(Exception oException)
        {
            return BaseResult.failed(oException.getMessage());
        }
        String dataDecrypt = RSAUtil.publicDecrypt(dataEncrypt, oRSAPublicKey);
        return BaseResult.success(dataDecrypt);
    }   

    @ApiOperation(value ="测试根据userId获取toekn",notes = "此接口用于根据userId获取toekn")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @PostMapping("/getTokenByUserId")
    public BaseResult getTokenByUserId(@RequestParam @NotNull(message = "userId不能为空") Long userId)
    {  
        YxSysUserEntity user = userMapper.selectOne(new LambdaQueryWrapper<YxSysUserEntity>()
                .eq(YxSysUserEntity::getUserId, userId)
                .eq(YxSysUserEntity::getUserStatus, 1)
        );
        LoginUserVo loginUserVo = getLoginUserVo(user);
        return BaseResult.success(loginUserVo);
    }

    @ApiOperation(value ="解析toekn信息",notes = "此接口用于解析toekn信息")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @PostMapping("/parsingToken")
    public BaseResult parsingToken(@RequestParam @NotBlank(message = "token不能为空") String token)
    {  
        return BaseResult.success(JwtUtil.parseToken(token));
    } 

    @ApiOperation(value ="base64Decode",notes = "此接口用于base64Decode")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @PostMapping("/base64Decode")
    public BaseResult base64Decode(@RequestParam @NotBlank(message = "token不能为空") String token)
    {
        System.out.println("ecodeGBK:");
        System.out.println(MyBase64.decodeGBK(token));
        System.out.println("decodeGB2312:");
        System.out.println(MyBase64.decodeGB2312(token));
        System.out.println("decodeUFF8:");
        System.out.println(MyBase64.decodeUFF8(token));
        return BaseResult.success(MyBase64.decodeUFF8(token));
       
    }

    @ApiOperation(value ="tokenToJsonObject",notes = "此接口用于tokenToJsonObject")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @PostMapping("/tokenToJsonObject")
    public BaseResult tokenToJsonObject(@RequestParam @NotBlank(message = "token不能为空") String token)
    {
        DecodedJWT oDecodedJWT = null;
        try 
        {
            oDecodedJWT = JWT.decode(token);
        } 
        catch (JWTDecodeException e) 
        {
            System.out.println("TokenUtil->getTokenInfoByTokenNoVerify  e.getMessage():" + e.getMessage());
            return BaseResult.failed(e.getMessage());
        }
        return BaseResult.success(JsonUtils.toJson(oDecodedJWT));
       
    }    

    @ApiOperation(value ="tookenJWTDecode",notes = "此接口用于tookenJWTDecode")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @PostMapping("/tookenJWTDecode")
    public BaseResult tookenJWTDecode(@RequestParam @NotBlank(message = "token不能为空") String token)
    {
        StringBuilder oStringBuilder = new StringBuilder();
        DecodedJWT oDecodedJWT = null;
        try 
        {
            oDecodedJWT = JWT.decode(token);
        } 
        catch (JWTDecodeException e) 
        {
            System.out.println("TokenUtil->getTokenInfoByTokenNoVerify  e.getMessage():" + e.getMessage());
            return BaseResult.failed(e.getMessage());
        }
        Map<String, Claim> map = oDecodedJWT.getClaims();
        
        Claim oClaim = map.get("expireTime");
        String Tmp = "expireTime=" + oClaim.asDate() + "  ";
        oStringBuilder.append(Tmp);
        System.out.println(Tmp);

        oClaim = map.get("userId");
        Tmp = "userId=" + oClaim.asLong() + "  ";
        oStringBuilder.append(Tmp);
        System.out.println(Tmp);

        oClaim = map.get("checkCode");
        Tmp = "checkCode=" + oClaim.asLong() + "  ";
        oStringBuilder.append(Tmp);
        System.out.println(Tmp);

        oClaim = map.get("token");
        Tmp = "token=" + oClaim.asString() + "  ";
        oStringBuilder.append(Tmp);
        System.out.println(Tmp);
        oStringBuilder.append("======================================================================================");
        map.forEach((k,v)->{
            //Claim oClaimTmp = map.get(k);
            String tmpInner = k + "=" ;
            if(v.isNull()){
                tmpInner = tmpInner + "null  ";
            }
            else{
                if(k.equals("token")){
                    tmpInner = tmpInner + v.asString() + "  type=" + v.getClass();
                }
                else{
                    tmpInner = tmpInner + String.valueOf(v.asLong()) + "  type=" + v.getClass();
                }
            }
            System.out.println(tmpInner);
            oStringBuilder.append(tmpInner);
        });
        
        return BaseResult.success(oStringBuilder.toString());
    }  

    @ApiOperation(value ="getUserIdFromToken",notes = "此接口用于JwtUtil.getUserIdFromToken")
    @ApiResponses({@ApiResponse(code = 200,message = "OK",response = BaseResult.class),})
    @PostMapping("/getUserIdFromToken")
    public BaseResult getUserIdFromToken(@RequestParam @NotBlank(message = "token不能为空") String token)
    {
        return BaseResult.success(JwtUtil.getUserIdFromToken(token));
    }
    
    
    
    
    
    
    /**
     * 登录返回信息
     * @param user
     * @return
     */
    private LoginUserVo getLoginUserVo(YxSysUserEntity user) {
        LoginUserVo loginUserVo = new LoginUserVo();
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtil.copyProperties(user, userInfoVo);
        long checkCode = System.currentTimeMillis();
        UserTokenVo userTokenVo = new UserTokenVo();
        userTokenVo.setUserId(user.getUserId());
        BeanUtil.copyProperties(user, userTokenVo);
        userTokenVo.setCheckCode(checkCode);
        userTokenVo.setExpirationDate(LocalDateTime.now().plusMinutes(30));
        userTokenVo.setMobilePhone(user.getMobilePhone());
        String token = JwtUtil.generateToken(userTokenVo, checkCode);
        loginUserVo.setUser(userInfoVo);
        loginUserVo.setToken(token);
        return loginUserVo;
    }
   
}
